package com.example.service.impl;

import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.result.Result;
import com.example.common.result.YiFeiException;
import com.example.entity.dto.EageDto;
import com.example.entity.dto.TicketDto;
import com.example.entity.dto.WorkOrderProcessDto;
import com.example.entity.dto.ZPX.ZpxJiTaiZhiPaiDto;
import com.example.entity.hz.MOCTA;
import com.example.entity.hz.Tickets;
import com.example.entity.mysql.Workresource;
import com.example.entity.vo.gd.CmsMqVoEnglish;
import com.example.entity.vo.gd.CraftVo;
import com.example.entity.vo.gd.TicketVo;
import com.example.entity.vo.gd.WorkOrderProcessVo;
import com.example.entity.yifei.*;
import com.example.enums.MOCStatusEnum;
import com.example.exception.CustomException;
import com.example.mapper.*;
import com.example.mapper.pc.WorkresourceMapper;
import com.example.service.TicketsService;
import com.example.untils.MyTopologicalSort;
import com.example.untils.SecurityUtils;
import com.example.untils.StringUtils;
import com.example.untils.TimeUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
@Log4j2
public class TicketsServiceImpl extends ServiceImpl<TicketsMapper,Tickets> implements TicketsService {

    @Autowired
    private MoctyxianzhiMapper moctyxianzhiMapper;
    @Resource
    private TicketsMapper ticketsMapper;
    @Autowired
    private CmsmwMapper cmsmwMapper;
    @Resource
    private CopmaMapper copmaMapper;
    @Autowired
    private MoctyMapper moctyMapper;
    @Autowired
    private MoctaMapper moctaMapper;
    @Autowired
    private WorkresourceMapper workresourceMapper;
    @Autowired
    private CmsmdMapper cmsmdMapper;

    @Override
    public Result<List<CmsMqVoEnglish>> queryTicketDb(String mq003) {
        try{
            List<CmsMqVoEnglish> cmsMqVoList = this.ticketsMapper.queryTicketDb(mq003);
            return Result.ok(cmsMqVoList);
        }catch (Exception e){
            throw new YiFeiException(500, "查询工单单别发生异常:"+e.getMessage());
        }
    }

    @Override
    public Result<List<com.mgkj.dao.share.vo.WorkCenterVo>> queryWorkCenterVo() {
        try{
            List<com.mgkj.dao.share.vo.WorkCenterVo> workCenterVoList = this.ticketsMapper.queryWorkCenterVo();
            return Result.ok(workCenterVoList);
        }catch (Exception e){
            throw new YiFeiException(500, "查询工作中心信息发生异常:"+e.getMessage());
        }
    }

    @Override
    public Result queryTicketIpAge(Integer current, Integer size, TicketDto ticketDto) {
        try{
            Map<String,Object> map = new HashMap<>();
            PageHelper.startPage(current,size);
            List<TicketVo> ticketVoList = this.ticketsMapper.queryTicketIpAge(ticketDto);
            PageInfo<TicketVo> ticketVoPageInfo = new PageInfo<>(ticketVoList);
            map.put("pages",ticketVoPageInfo.getPages());
            map.put("total",ticketVoPageInfo.getTotal());
            map.put("list",ticketVoPageInfo.getList());
            return Result.ok(map);
        }catch (Exception e){
            throw new YiFeiException(500, "工单分页查询发生异常"+e.getMessage());
        }
    }

    @Override
    public Result<List<WorkOrderProcessVo>> queryWorkOrderProcess(String ta001, String ta002) {
        try{
            List<WorkOrderProcessVo> workOrderProcessVoList = this.ticketsMapper.queryWorkOrderProcess(ta001, ta002);
            if (!workOrderProcessVoList.isEmpty()){
                for(WorkOrderProcessVo item : workOrderProcessVoList) {
                    item.setBeforeProcessNo(moctyxianzhiMapper.selBeforeProcessNo(item.getTa001(), item.getTa002(), item.getTa003()));
                    item.setZpxList(moctyxianzhiMapper.selWorkResource(item.getTa001().trim()+item.getTa002().trim()+item.getTa003().trim()));
                }
            }
            return Result.ok(workOrderProcessVoList);
        }catch (Exception e){
            throw new YiFeiException(500, "通过工单的单别单号查询工单工艺发生异常错误:"+e.getMessage());
        }
    }

    @Override
    public Result<List<CraftVo>> queryCraft(String division){
        try{
            List<CraftVo> craftVoList = this.ticketsMapper.queryCraft(division);
            return Result.ok(craftVoList);
        }catch (Exception e){
            throw new YiFeiException(500, "查询工艺信息发生异常:"+e.getMessage());
        }
    }

    @Override
    @DSTransactional
    public Result<?> insertOrUpdateWorkOrderProcess(List<WorkOrderProcessDto> workOrderProcessDtoList) {
        if (!workOrderProcessDtoList.isEmpty()){
            Mocty mocty = moctyMapper.selectOne(new LambdaQueryWrapper<Mocty>().eq(Mocty::getUdf05, workOrderProcessDtoList.get(0).getTa001().trim() + workOrderProcessDtoList.get(0).getTa002().trim()));
            if(mocty == null) {
                throw new CustomException("500", "大工单不存在");
            }
            // 更新大工单的状态
            mocty.setUdf01(MOCStatusEnum.DaiJinZhan.getValue());
            moctyMapper.update(mocty, new LambdaQueryWrapper<Mocty>().eq(Mocty::getUdf05, mocty.getUdf05()));
            Boolean b1 = this.ticketsMapper.deleteWorkOrderProcess(workOrderProcessDtoList.get(0).getTa001(), workOrderProcessDtoList.get(0).getTa002(),null);
            moctyxianzhiMapper.delete(new LambdaQueryWrapper<Moctyxianzhi>().eq(Moctyxianzhi::getTa001, workOrderProcessDtoList.get(0).getTa001())
                    .eq(Moctyxianzhi::getTa002, workOrderProcessDtoList.get(0).getTa002()));
            MOCTA mocta = moctaMapper.selectOne(new LambdaQueryWrapper<MOCTA>().eq(MOCTA::getTA001, workOrderProcessDtoList.get(0).getTa001()).eq(MOCTA::getTA002, workOrderProcessDtoList.get(0).getTa002()));
            if(mocta == null) {
                throw new CustomException("500", "大工单不存在");
            }
            Cmsmd cmsmd = cmsmdMapper.selectOne(new LambdaQueryWrapper<Cmsmd>().eq(Cmsmd::getMd001, mocta.getTA021()));
            int idx = 1;
            Map<String, Integer> map = new HashMap<>();
            // 判断工序之间存不存在环
            for(WorkOrderProcessDto t : workOrderProcessDtoList) {
                map.put(t.getTa003().trim(), idx);
                idx++;
            }
            List<EageDto> eageList = new ArrayList<>();
            for(WorkOrderProcessDto t : workOrderProcessDtoList) {
                if(t.getBeforeProcessNo().isEmpty()) continue;
                Integer count = map.get(t.getTa003().trim());
                for(String item : t.getBeforeProcessNo()) {
                    Integer integer = map.get(item.trim());
                    eageList.add(new EageDto(count, integer));
                    Moctyxianzhi moctyxianzhi = new Moctyxianzhi();   // 前置工序表
                    moctyxianzhi.setTa001(t.getTa001());
                    moctyxianzhi.setTa002(t.getTa002());
                    moctyxianzhi.setTa003(t.getTa003());
                    moctyxianzhi.setQzta003(item);
                    moctyxianzhiMapper.insert(moctyxianzhi);
                }
            }
            MyTopologicalSort myTopologicalSort = new MyTopologicalSort();
            int cycle = myTopologicalSort.haveCycle(workOrderProcessDtoList.size(), eageList);
            if(cycle == -1) {
                throw new CustomException("500", "前置关系维护中，存在死循环...");
            }

            for(WorkOrderProcessDto t : workOrderProcessDtoList) {
                if(StringUtils.isEmpty(t.getTa004())) {
                    // 新增工艺
                    Cmsmw cmsmw = new Cmsmw();
                    cmsmw.setCreator("ERP");
                    cmsmw.setCreateDate(TimeUtils.getNowTime());
                    cmsmw.setMw001(UUID.randomUUID().toString().toUpperCase());
                    cmsmw.setMw002(t.getMw002());
                    cmsmw.setMw004("1");
                    cmsmw.setMw005(mocta.getTA021());
                    cmsmw.setMw006(cmsmd.getMd002());
                    cmsmwMapper.insert(cmsmw);
                    t.setTa004(cmsmw.getMw001().trim());
                }
                String UDF05 = t.getTa001().trim() + t.getTa002().trim() + t.getTa003().trim();
                Mocty mocty2 = moctyMapper.selectOne(new LambdaQueryWrapper<Mocty>().eq(Mocty::getUdf05, UDF05));
                if(mocty2 == null) {   // 这边要把所有工序的都插入到MOCTY里面去
                    mocty2 = new Mocty();
                    mocty2.setTy001(mocta.getTA001().trim());
                    mocty2.setTy002(mocta.getTA002().trim());
                    mocty2.setTy003(mocty2.getTy001() + mocty2.getTy002() + t.getTa003().trim());   // 区分是哪个
                    mocty2.setTy004(mocta.getTA015().doubleValue());
                    mocty2.setTy009("****");
                    mocty2.setTy019(t.getTa003());
                    mocty2.setUdf01(MOCStatusEnum.DaiPaiJi.getValue());
                    mocty2.setUdf10(TimeUtils.getFullNowTime());  // 机台指派时间
                    mocty2.setUdf11(mocty2.getTy001());
                    mocty2.setUdf12(mocty2.getTy002());
                    mocty2.setUdf05(UDF05);
                    mocty2.setUdf54(1D);
                    moctyMapper.insert(mocty2);
                }
                workresourceMapper.delete(new LambdaQueryWrapper<Workresource>().eq(Workresource::getProductLineId, UDF05));
                for(ZpxJiTaiZhiPaiDto zpx : t.getZpxList()) {
                    Workresource workresource = new Workresource();
                    workresource.setWorkResourceId(UUID.randomUUID().toString());
                    workresource.setWorkSingle(t.getTa001());
                    workresource.setWorkNo(t.getTa002());
                    workresource.setProcessNo(t.getTa003());
                    workresource.setProcessId(t.getTa004());
                    workresource.setResourceGroupId(zpx.getResourceGroupId());
                    workresource.setResourceId(zpx.getResourceId());
                    workresource.setDate(t.getUdf04());  //
                    workresource.setBeat(t.getUdf51());
                    workresource.setQuota(t.getUdf52());
                    workresource.setCreator(SecurityUtils.getLoginUser().getUsername());
                    workresource.setCreateTime(TimeUtils.getFullNowTime());
                    workresource.setProductLineId(UDF05);
                    workresource.setResourceTypeId(zpx.getResourceType());
                    workresource.setPeopleNum(Integer.parseInt(t.getUdf01()));
                    workresource.setLeaderNo(t.getUdf02());
                    workresource.setLeaderName(t.getUdf03());
                    if(zpx.getResourceType().equals(1) || zpx.getResourceType().equals(2)) {
                        mocty2.setTy009(zpx.getResourceId().toString());
                        mocty2.setUdf01(MOCStatusEnum.DaiJinZhan.getValue());
                        moctyMapper.update(mocty2, new LambdaQueryWrapper<Mocty>().eq(Mocty::getUdf05, mocty2.getUdf05()));
                    }
                    workresourceMapper.insert(workresource);
                }
            }
            Boolean b = this.ticketsMapper.insertOrUpdateWorkOrderProcess(workOrderProcessDtoList);

            return Result.ok();
        }
        return Result.fail("参数错误,请输入正确的参数!"+workOrderProcessDtoList);
    }

    @Override
    @Transactional
    public Result<?> deleteCraft(String ta001, String ta002) {
        try{
            Boolean b = this.ticketsMapper.deleteWorkOrderProcess(ta001,ta002,null);
            if (b){
                this.ticketsMapper.deleteSubprocesses(ta001,ta002,null);
            }
            return Result.ok();
        }catch (Exception e){
            throw new YiFeiException(500, "删除工单工艺发生异常:"+e.getMessage());
        }
    }

    @Override
    public Result<List<Copma>> listCustomer() {
        LambdaQueryWrapper<Copma> wrapper = new LambdaQueryWrapper<>();
        List<Copma> list = copmaMapper.selectList(wrapper);
        return Result.ok(list);
    }
}
